#include "TaskQueue.h"

TaskQueue::TaskQueue(size_t queSize)
: _queSize(queSize)
, _que()
, _mutex()
, _notEmpty(_mutex)
, _notFull(_mutex)
{

}

TaskQueue::~TaskQueue()
{

}

bool TaskQueue::empty() const
{
    return 0 == _que.size();
}

bool TaskQueue::full() const
{
    return _que.size() == _queSize;
}

void TaskQueue::push(const int &value)
{
    //RAII的思想：利用栈对象的生命周期管理资源
    MutexLockGuard autoLock(_mutex);
    //因为TaskQueue是共享资源，所以需要先上锁
    /* _mutex.lock(); */

    //虚假唤醒的问题
    /* if(full()) */
    while(full())
    {
        //如果为满，那么等待在该条件变量上的线程需要睡眠
        _notFull.wait();
    }

    //只有TaskQueue是不满，才可以push数据
    _que.push(value);

    /* if(...) */
    /* { */
    /*     //.... */
    /*     return ; */
    /* } */
    //如果TaskQueue有数据，那么就需要唤醒对应的线程消费数据
    _notEmpty.notify();

    //用完之后就释放锁
    /* _mutex.unlock(); */
}

int TaskQueue::pop()
{
    MutexLockGuard autoLock(_mutex);
    //因为TaskQueue是共享资源，所以需要先上锁
    /* _mutex.lock(); */

    /* if(empty()) */
    while(empty())
    {
        //如果为空，那么等待在该条件变量上的线程需要睡眠
        _notEmpty.wait();
    }

    //只有TaskQueue是不空，才可以pop数据
    int tmp = _que.front();//先获取该值
    _que.pop();//然后在进行删除

    //如果TaskQueue有空位置，那么就需要唤醒对应的线程生产数据
    _notFull.notify();

    //用完之后就释放锁
    /* _mutex.unlock(); */

    return tmp;
}
